package com.example.origin.finance.trade.dto.impl;

import com.example.origin.finance.dto.XueqiuCashFlow;
import com.example.origin.finance.dto.XueqiuIndicator;
import com.example.origin.finance.trade.dto.Analyst;
import com.example.origin.finance.trade.dto.Conclusion;
import com.example.origin.finance.trade.dto.InfoResource;
import com.example.origin.finance.trade.enums.Action;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class GreenAnalyst extends Analyst {
    @Override
    protected Conclusion conclusion() {
        InfoResource infoResource = getInfoResource();
        return new Conclusion(infoResource, klineFlag() && valueFlag() && cashflowFlag() && indicatorFlag() ? Action.BUY : Action.SELL);
    }

    public boolean klineFlag() {
        if (getKline().getPe() == null || getKline().getMarket_capital() == null) {
            return false;
        }
        if (getKline().getPe() >= 10 && getKline().getPe() <= 35) {
            if (getKline().getMarket_capital() >= 1E9 && getKline().getMarket_capital() <= 2E10) {
                return true;
            }
        }
        return false;
    }

    public boolean cashflowFlag() {
        if (getTwoCashFlows().stream().anyMatch(e -> e.getNcfFromOa() == null || e.getCashReceivedOfSalesService() == null)) {
            return false;
        }
        if (getTwoCashFlows().get(0).getNcfFromOa() > getTwoCashFlows().get(1).getNcfFromOa()) {
            if (getTwoCashFlows().get(0).getCashReceivedOfSalesService() > getTwoCashFlows().get(1).getCashReceivedOfSalesService()) {
                return true;
            }
        }
        return false;
    }


    public boolean indicatorFlag() {
        if (getTwoIndicators().stream().anyMatch(e -> e.getAvgRoe() == null || e.getRop() == null)) {
            return false;
        }
        if (getTwoIndicators().get(0).getAvgRoe() >= 10 && getTwoIndicators().get(0).getAvgRoe() > getTwoIndicators().get(1).getAvgRoe() && getTwoIndicators().get(0).getRop() >= 200 && getTwoIndicators().get(0).getRop() > getTwoIndicators().get(1).getRop()) {
            return true;
        }
        return false;
    }


    public boolean valueFlag() {
        if (CollectionUtils.isEmpty(getMoreCashFlows()) || CollectionUtils.isEmpty(getMoreIndicators())) {
            return false;
        }
        List<XueqiuIndicator> indicators = getMoreIndicators().stream().filter(e -> e.getNetProfitAtsopcYoy() != null).sorted(Comparator.comparing(XueqiuIndicator::getReportDate, Comparator.reverseOrder())).limit(7).collect(Collectors.toList());
        if (indicators.size() < 7) {
            return false;
        }
        List<XueqiuCashFlow> cashFlows = getMoreCashFlows().stream().filter(e -> e.getFinalBalanceOfCce() != null).sorted(Comparator.comparing(XueqiuCashFlow::getReportDate, Comparator.reverseOrder())).limit(7).collect(Collectors.toList());
        if (cashFlows.size() < 7) {
            return false;
        }
        Double profitRate = indicators.stream().sorted(Comparator.comparing(XueqiuIndicator::getNetProfitAtsopcYoy, Comparator.reverseOrder())).skip(1).limit(5).collect(Collectors.averagingDouble(XueqiuIndicator::getNetProfitAtsopcYoy));
        Double finalCash = cashFlows.stream().sorted(Comparator.comparing(XueqiuCashFlow::getFinalBalanceOfCce, Comparator.reverseOrder())).skip(1).limit(5).collect(Collectors.averagingDouble(XueqiuCashFlow::getFinalBalanceOfCce));
        Double result = valueCalc(finalCash, 0.05d, profitRate / 100, profitRate / 200, 5);
        Double marketCapital = getKline().getMarket_capital();
        if (marketCapital != null && result > marketCapital) {
            return true;
        }

        return false;
    }

    private static Double valueCalc(Double freeMoney, Double tiexianlv, Double zengzhanglv, Double zengzhanglv_yihou, Integer year) {
        return valueCalc(String.valueOf(freeMoney), String.valueOf(tiexianlv), String.valueOf(zengzhanglv), String.valueOf(zengzhanglv_yihou), year);
    }

    private static Double valueCalc(String freeMoney, String tiexianlv, String zengzhanglv, String zengzhanglv_yihou, Integer year) {
        if (Double.parseDouble(tiexianlv) < Double.parseDouble(zengzhanglv_yihou)) {
            // 贴现率应该大于年后增长率
            zengzhanglv_yihou = (Double.parseDouble(tiexianlv) - 0.01) + "";
        }
        // 前十年贴现
        BigDecimal sum_zhexian = new BigDecimal(0);
        BigDecimal ziyouxianjin = new BigDecimal(0);
        for (int i = 0; i < year; i++) {
            ziyouxianjin = new BigDecimal(freeMoney).multiply(BigDecimal.valueOf(1 + Double.parseDouble(zengzhanglv)).pow(i + 1));
            BigDecimal zhexian = ziyouxianjin.divide(BigDecimal.valueOf(1 + Double.parseDouble(tiexianlv)).pow(i + 1), RoundingMode.HALF_UP);
            sum_zhexian = zhexian.add(sum_zhexian);
        }
        // 十年之后贴现
        BigDecimal ziyouxianjin_yihou = ziyouxianjin.multiply(BigDecimal.valueOf(1 + Double.parseDouble(zengzhanglv_yihou))).multiply(BigDecimal.valueOf(1 + Double.parseDouble(tiexianlv)).divide(BigDecimal.valueOf(Double.parseDouble(tiexianlv) - Double.parseDouble(zengzhanglv_yihou)), RoundingMode.HALF_UP));
        BigDecimal sum_zhexian_yihou = ziyouxianjin_yihou.divide(BigDecimal.valueOf(1 + Double.parseDouble(tiexianlv)).pow(year + 1), RoundingMode.HALF_UP);
        return sum_zhexian_yihou.add(sum_zhexian).setScale(1, RoundingMode.HALF_UP).doubleValue();
    }
}
